﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace QuantumQuest
{
    public partial class QQBody : UserControl
    {
        
        public QQVector2 _position;
        protected QQVector2 _velocity;
        protected QQVector2 _acceleration;
        protected double _mass;
        protected int _zIndex;
        protected bool _isStationary;
        protected bool _isConstantAccel;
        protected QQVector2 _heading;
        protected Dynamics _dynamics;

        protected TransformGroup _transGroup;
        protected RotateTransform _rotate;
        protected ScaleTransform _scale;

        protected Path _outlinePath;


        public QQBody(QQVector2 position, QQVector2 velocity, QQVector2 accleration, 
                      double mass, int zIndex,bool isStationary, bool isConstantAccel)
        {

            InitializeBody();
            

            _position = position;
            _velocity = velocity;
            _acceleration = accleration;
            _heading.X = _velocity.X;
            _heading.Y = _velocity.Y;
            _heading.Normalize();
            _zIndex = zIndex;

            _mass = mass;
            _isStationary = isStationary;
            _isConstantAccel = isConstantAccel;

            _dynamics = new Dynamics(_position, _velocity, _acceleration);

            UpdateBody();
            
        }
        public QQBody()
        {
            InitializeBody();
            
            UpdateBody();
        }
        public struct Dynamics
        {
            public QQVector2 Position, Velocity, Acceleration;
            public Dynamics(QQVector2 p, QQVector2 v, QQVector2 a)
            {
                Position = new QQVector2();
                Velocity = new QQVector2();
                Acceleration = new QQVector2();

                Position = p;
                Velocity = v;
                Acceleration = a;

            }
            public override string ToString()
            {
                string ret="";
                ret +="Position: " + Convert.ToString(Math.Round(Position.X,2)) + "\t" + Convert.ToString(Math.Round(Position.Y,2)) + "\n"
                    + "Velocity: " + Convert.ToString(Math.Round(Velocity.X,3)) + "\t" + Convert.ToString(Math.Round(Velocity.Y,3)) + "\n"
                    + "Acceleration: " + Convert.ToString(Math.Round(Acceleration.X,4)) + "\t" + Convert.ToString(Math.Round(Acceleration.Y,4)) + "\n";
                return ret;
            }

        }
        private void InitializeBody()
        {
            _position = new QQVector2(0, 0);
            _velocity = new QQVector2(0, 0);
            _acceleration = new QQVector2(0, 0);
            _heading = new QQVector2(0, 0);

            _transGroup = new TransformGroup();
            _rotate = new RotateTransform();
            _scale = new ScaleTransform();
        }
        public Dynamics DynamicsParameters
        {
            get
            {
                return _dynamics;
            }
            set
            {
                _dynamics = value;
                _position = _dynamics.Position;
                _velocity = _dynamics.Velocity;
                _acceleration = _dynamics.Acceleration;
                UpdateBody();
            }
        }
        public Path OutlinePath
        {
            get
            {
                return _outlinePath;
            }
        }
        public QQVector2 PositionVec
        {
            get
            {
                return _position;
            }
            set
            {

                _position = value;
                UpdateBody();

            }
        }
        public QQVector2 VelocityVec
        {
            get
            {
                return _velocity;
            }
            set
            {

                _velocity = value;
                UpdateBody();

            }
        }
        public QQVector2 AccelerationVec
        {
            get
            {
                return _acceleration;
            }
            set
            {

                _acceleration = value;
                UpdateBody();

            }
        }
        public double Mass
        {
            get
            {
                return _mass;
            }
            set
            {

                _mass = value;
                UpdateBody();

            }
        }
        public int ZIndex
        {
            get
            {
                return _zIndex;
            }
            set
            {
                _zIndex = value;
                UpdateBody();
            }
        }
        public ScaleTransform ScaleTrans
        {
            get
            {
                return _scale;
            }
            set
            {
                _scale = value;
                UpdateBody();
            }
        }
        public QQVector2 Heading
        {
            get
            {
                return _heading;
            }
            set
            {

                _heading = value;
                _heading.Normalize();
                UpdateBody();
            }
        }
        public bool IsStationary
        {
            get
            {
                return _isStationary;
            }
            set
            {
                _isStationary = value;
                UpdateBody();
            }
        }
        public bool IsConstantAccel
        {
            get
            {
                return _isConstantAccel;
            }
            set
            {
                _isConstantAccel = value;
                UpdateBody();
            }
        }
        public void RotateCounterClockWRad(double drad)
        {
            _heading.ThetaRad += drad;
            UpdateBody();
        }
        public void RotateCounterClockWDeg(double ddeg)
        {
            _heading.ThetaDeg += ddeg;
            UpdateBody();
        }
        public void RotateClockWRad(double drad)
        {
            RotateCounterClockWRad(((2.0) * (Math.PI)) - drad);
            UpdateBody();
        }
        public void RotateClockWDeg(double ddeg)
        {
            RotateCounterClockWDeg(360 - ddeg);
            UpdateBody();
        }

        public void UpdateBody()
        {
            //so when we change a transformation, do we have to run through this again, or is it taken care of?
            this.RenderTransformOrigin = new Point(0.5, 0.5);//transform about the center of the body

            _transGroup = new TransformGroup();
           
            _rotate = new RotateTransform();
            _scale = new ScaleTransform();

            _rotate.Angle = 360 - _heading.ThetaDeg;//so it says it wants it in degrees clockwise...so this should work?
            _dynamics.Position = _position;
            _dynamics.Velocity = _velocity;
            _dynamics.Acceleration = _acceleration;
            
            //_translate.X = _position.X;//WRONG WRONG WRONG; needs to be relative to some point
            //_translate.X = _position.Y;//likewise
            this.SetValue(Canvas.LeftProperty, _position.X);
            this.SetValue(Canvas.TopProperty, _position.Y);
            this.SetValue(Canvas.ZIndexProperty, _zIndex);

            
            _transGroup.Children.Add(_rotate);
            _transGroup.Children.Add(_scale);

            //this.RenderTransform = _transGroup;

        }

    }
}
